package com.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.StrUtil;
import com.controller.SignTaskController;
import com.dao.*;
import com.entity.SignTask;
import com.entity.Student;
import com.entity.StudentSignTask;
import com.entity.Teacher;
import com.exception.CustomException;
import com.exception.CustomTransactionalException;
import com.form.signTask.PageListSignTask;
import com.from.signTask.AddSignTaskFrom;
import com.vo.Msg;
import com.vo.PageVo;
import com.vo.signTask.DisplaySignTask;
import com.vo.signTask.SignDetail;
import com.vo.signTask.SignTaskDetail;
import com.vo.signTask.StuSignList;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Version: V1.0    <br/>
 * Datetime:   2022/5/13 22:11   <br/>
 * Description: ${DES}
 *
 * @author: chen
 */
@Slf4j
@Service
public class SignTaskService {

    @Resource
    private SignTaskMapper signTaskMapper;

    @Resource
    private StudentSignTaskMapper studentSignTaskMapper;

    @Resource
    private TeacherMapper teacherMapper;

    @Resource
    private StudentMapper studentMapper;

    public int deleteByPrimaryKey(Long id) {
        return signTaskMapper.deleteByPrimaryKey(id);
    }


    public int insert(SignTask record) {
        return signTaskMapper.insert(record);
    }


    public int insertSelective(SignTask record) {
        return signTaskMapper.insertSelective(record);
    }


    public SignTask selectByPrimaryKey(Long id) {
        return signTaskMapper.selectByPrimaryKey(id);
    }


    public int updateByPrimaryKeySelective(SignTask record) {
        return signTaskMapper.updateByPrimaryKeySelective(record);
    }


    public int updateByPrimaryKey(SignTask record) {
        return signTaskMapper.updateByPrimaryKey(record);
    }

    @Transactional(rollbackFor = CustomTransactionalException.class)
    public void addSignTask(AddSignTaskFrom addFrom) {
        // 组装数据
        SignTask signTask = new SignTask();
        signTask.setTaskDes(addFrom.getDescription());
        signTask.setTeacherId(addFrom.getTeacherId());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            signTask.setStartTime(sdf.parse(addFrom.getStartTime()));
            signTask.setEndTime(sdf.parse(addFrom.getEndTime()));
            if (signTask.getStartTime().getTime() >= signTask.getEndTime().getTime()) {
                throw new CustomException("开始时间不能大于结束时间");
            }
        } catch (ParseException e) {
            throw new CustomException("时间格式错误");
        }
        signTask.setCreateTime(new java.util.Date());
        // 添加任务
        int recordId = signTaskMapper.insert(signTask);
        if (recordId == 0) {
            throw new CustomTransactionalException("添加任务失败");
        }
        log.info("add signTask record id:{}", signTask.getId());
        List<StudentSignTask> studentSignTaskList = new ArrayList<>(addFrom.getParticipants().size());
        addFrom.getParticipants().forEach(studentId -> {
            StudentSignTask studentSignTask = new StudentSignTask();
            studentSignTask.setStudentId(studentId);
            studentSignTask.setFinish(0);
            studentSignTask.setTaskId(signTask.getId());
            studentSignTaskList.add(studentSignTask);
        });
        // 添加学生任务
        if (studentSignTaskList.size() > 0) {
            int studentTaskRecordId = studentSignTaskMapper.batchInsert(studentSignTaskList);
            if (studentTaskRecordId != studentSignTaskList.size()) {
                throw new CustomTransactionalException("添加学生任务失败");
            }
        }
    }

    /**
     * 分页查询签到任务
     *
     * @param pageListSignTask 查询条件
     * @return 签到任务列表
     */
    public PageVo<DisplaySignTask> pageListSignTask(PageListSignTask pageListSignTask) throws ParseException {
        PageVo<DisplaySignTask> pageVo = new PageVo<DisplaySignTask>().setCurrentAndSize(pageListSignTask);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date startTime = null;
        Date endTime = null;
        if (StrUtil.isNotEmpty(pageListSignTask.getStartTime())) {
            startTime = sdf.parse(pageListSignTask.getStartTime());
        }
        if (StrUtil.isNotEmpty(pageListSignTask.getEndTime())) {
            endTime = sdf.parse(pageListSignTask.getEndTime());
        }
        // 设置总的记录条数
        pageVo.setTotal(counterSignTask(pageListSignTask, startTime, endTime));
        // 当前查询页数
        int pageIndex = pageListSignTask.getPageIndex();
        // 判断当前页数是否超过总页数
        pageIndex = pageIndex > pageVo.getPages() ? 1 : pageIndex;
        pageVo.setPageIndex(pageIndex);
        // 查询数据
        List<SignTask> signTaskList = signTaskMapper.pageListSignTask(pageListSignTask,
                (pageIndex - 1) * pageVo.getPageSize(), pageVo.getPageSize(), startTime, endTime);
        List<DisplaySignTask> displaySignTaskList = new ArrayList<>(signTaskList.size());
        // 获取所有的教师列表
        Map<Long, String> teacherMap = teacherMapper.selectAll().stream().collect(Collectors.toMap(Teacher::getId, Teacher::getJiaoshixingming));
        signTaskList.forEach(signTask -> {
            DisplaySignTask displaySignTask = new DisplaySignTask();
            BeanUtil.copyProperties(signTask, displaySignTask, CopyOptions.create().setIgnoreNullValue(true));
            // 查询完成情况
            List<StudentSignTask> studentSignTaskList = studentSignTaskMapper.selectByTaskId(signTask.getId());
            int finish = 0;
            for (StudentSignTask studentSignTask : studentSignTaskList) {
                if (studentSignTask.getFinish() == 1) {
                    finish++;
                }
            }
            displaySignTask.setTeacherName(teacherMap.getOrDefault(signTask.getTeacherId(), ""));
            displaySignTask.setSignNumber(finish);
            displaySignTask.setTotalNumber(studentSignTaskList.size());
            displaySignTaskList.add(displaySignTask);
        });
        pageVo.setRecords(displaySignTaskList);
        return pageVo;
    }

    private Long counterSignTask(PageListSignTask pageListSignTask, Date startTime, Date endTime) {

        return signTaskMapper.counterSignTask(pageListSignTask, startTime, endTime);
    }

    /**
     * 删除签到任务
     */
    public void deleteSignTask(Long id) {
        // 删除签到任务
        int i = signTaskMapper.deleteByPrimaryKey(id);
        if (i != 1) {
            throw new CustomTransactionalException("删除签到任务失败");
        }
        // 删除签到任务的学生
        studentSignTaskMapper.deleteByTaskId(id);
    }

    public SignTaskDetail getSignTaskDetail(Long id) {
        SignTask signTask = signTaskMapper.selectByPrimaryKey(id);
        SignTaskDetail signTaskDetail = new SignTaskDetail();
        BeanUtil.copyProperties(signTask, signTaskDetail, CopyOptions.create().setIgnoreNullValue(true));
        // 查询学生信息
        List<StudentSignTask> studentSignTaskList = studentSignTaskMapper.selectByTaskId(id);
        List<Long> stuId = new ArrayList<>(studentSignTaskList.size());
        studentSignTaskList.forEach(studentSignTask -> {
            stuId.add(studentSignTask.getStudentId());
        });
        signTaskDetail.setStudentIdList(stuId);
        return signTaskDetail;
    }

    /**
     * 更新签到任务
     */
    @Transactional(rollbackFor = CustomTransactionalException.class)
    public void modifySignTask(AddSignTaskFrom addFrom) {
        // 获取签到任务编号
        Long id = addFrom.getId();
        // 删除签到任务
        deleteSignTask(id);
        // 新建签到任务
        addFrom.setId(null);
        addSignTask(addFrom);
    }

    public List<SignDetail> getSignDetail(Long id) {
        // 查询签到任务
        List<StudentSignTask> studentSignTaskList = studentSignTaskMapper.selectByTaskId(id);
        List<SignDetail> signDetailList = new ArrayList<>(studentSignTaskList.size());
        studentSignTaskList.forEach(studentSignTask -> {
            Long studentId = studentSignTask.getStudentId();
            Student student = studentMapper.selectByPrimaryKey(studentId);
            if (student != null) {
                SignDetail signDetail = new SignDetail();
                signDetail.setStudentId(student.getXueshengxuehao());
                signDetail.setName(student.getXueshengxingming());
                signDetail.setSignStatus(studentSignTask.getFinish());
                signDetail.setSignTime(studentSignTask.getSignTime());
                signDetailList.add(signDetail);
            }
        });
        signDetailList.sort(Comparator.comparing(SignDetail::getSignStatus));
        return signDetailList;
    }

    public List<StuSignList> getStuSignList(Long userId) {
        if (userId == null) {
            return null;
        }
        // 查询签到任务
        List<SignTask> signTaskList = signTaskMapper.getStudentSignTask(userId, new Date());
        // 获取所有的教师列表
        Map<Long, String> teacherMap = teacherMapper.selectAll().stream().collect(Collectors.toMap(Teacher::getId, Teacher::getJiaoshixingming));
        List<StuSignList> stuSignList = new ArrayList<>(signTaskList.size());
        signTaskList.forEach(signTask -> {
            StuSignList s = new StuSignList();
            s.setTaskId(signTask.getId());
            s.setSignName(signTask.getTaskDes());
            s.setStartTime(signTask.getStartTime());
            s.setEndTime(signTask.getEndTime());
            s.setTeacherName(teacherMap.getOrDefault(signTask.getTeacherId(), ""));
            stuSignList.add(s);
        });
        return stuSignList;
    }

    public Msg signIn(Long userId, Long signTaskId) {
        // 查询签到任务
        StudentSignTask studentSignTask = studentSignTaskMapper.selectByStudentIdAndTaskId(userId, signTaskId);
        if (studentSignTask == null || studentSignTask.getFinish() == 1) {
            return Msg.error("你已经签到过了");
        }
        SignTask signTask = signTaskMapper.selectByPrimaryKey(studentSignTask.getTaskId());
        // 签到超时
        if (signTask.getEndTime().before(new Date())) {
            return Msg.error("签到超时");
        }
        studentSignTask.setTaskId(null);
        studentSignTask.setStudentId(null);
        studentSignTask.setFinish(1);
        studentSignTask.setSignTime(new Date());
        int i = studentSignTaskMapper.updateByPrimaryKeySelective(studentSignTask);
        return i == 1 ? Msg.success() : Msg.error();
    }
}